import {
  BaseCommand,
  CENTEREVENTS,
  EventsRes,
  TrackBallControlState,
} from '@amcax/base';
import { csEvent } from '@app-base/common/events/EventCenter';
import panView from '@app-cad/assets/svg-icons/commands/common/pan-view.svg';
import rotateView from '@app-cad/assets/svg-icons/commands/common/rotate-view.svg';
import zoomView from '@app-cad/assets/svg-icons/commands/common/zoom-view.svg';
import { KEYBOARD_KEY } from '@app-cad/common/Constants';
import { MessageTip } from '@app-cad/common/utils/MessageTip';
import { ctx2, userEvents } from '@app-cad/module';

export const KEYBOARD_VIEW = 'keyboard_view';

export const cmdPanView: BaseCommand = {
  id: 'CmdPanView',
  label: 'command.controlMouse-pan',
  icon: 'commands/common/pan-view',
  invoke: controlMove,
  noHighlight: true,
  standalone: false,
  destory: setControlDefault,
};

export const cmdRotateView: BaseCommand = {
  id: 'CmdRotateView',
  label: 'command.controlMouse-rotate',
  icon: 'commands/common/rotate-view',
  invoke: controlRotate,
  noHighlight: true,
  standalone: false,
  destory: setControlDefault,
};

export const cmdZoomView: BaseCommand = {
  id: 'CmdZoomView',
  label: 'command.controlMouse-zoom',
  icon: 'commands/common/zoom-view',
  invoke: controlZoom,
  noHighlight: true,
  standalone: false,
  destory: setControlDefault,
};

function setControlDefault() {
  ctx2.viewer.sceneSetup.setToolBarControl(false);
  ToolbarMouseControlManager.state = TrackBallControlState.NONE;
  ctx2.viewer.sceneSetup.setMouseState(TrackBallControlState.NONE);
  csEvent().off(CENTEREVENTS.KEYUP, keyupEvent).setDefault();
  userEvents.emit(KEYBOARD_VIEW, { isSelected: false });
  document.body.style.cursor = 'auto';
  document.removeEventListener('mousedown', onMoveMouseDown, { capture: true });
  document.removeEventListener('mouseup', onMoveMouseUp, { capture: true });
  document.removeEventListener('mousedown', onRotateMouseDown, {
    capture: true,
  });
  document.removeEventListener('mouseup', onRotateMouseUp, { capture: true });
  document.removeEventListener('mousedown', onZoomMouseDown, { capture: true });
  document.removeEventListener('mouseup', onZoomMouseUp, { capture: true });
  document.removeEventListener('wheel', onMouseWheel, { capture: true });
}

function keyupEvent(e: EventsRes<KeyboardEvent>) {
  if (e.key === KEYBOARD_KEY.ESC) {
    setControlDefault();
  }
}

const setMouseStyle = (img: string) => {
  document.body.style.cursor = `url(${img}) 10 10, auto`;
};

const onDefaultMouseDown = (e, view, state) => {
  if (e.button === 1 && !e.ctrlKey) {
    ctx2.viewer.sceneSetup.setMouseState(TrackBallControlState.PAN);
    setMouseStyle(panView);
  } else if ((e.button === 1 && e.ctrlKey) || e.button === 2) {
    ctx2.viewer.sceneSetup.setMouseState(TrackBallControlState.ROTATE);
    setMouseStyle(rotateView);
  } else {
    ctx2.viewer.sceneSetup.setMouseState(state);
    setMouseStyle(view);
  }
};

const onMoveMouseDown = (e) => {
  onDefaultMouseDown(e, panView, TrackBallControlState.PAN);
};

const onMoveMouseUp = () => {
  setMouseStyle(panView);
};

const onRotateMouseDown = (e) => {
  onDefaultMouseDown(e, rotateView, TrackBallControlState.ROTATE);
};

const onRotateMouseUp = () => {
  setMouseStyle(rotateView);
};

const onZoomMouseDown = (e) => {
  onDefaultMouseDown(e, zoomView, TrackBallControlState.ZOOM);
};

const onZoomMouseUp = () => {
  setMouseStyle(zoomView);
};

const onMouseWheel = () => {
  setMouseStyle(zoomView);
};

function controlMove() {
  if (ToolbarMouseControlManager.state === TrackBallControlState.PAN) {
    setControlDefault();
    return;
  }
  csEvent()
    .setState('control-move')
    .on(CENTEREVENTS.KEYUP, keyupEvent)
    .addExit(setControlDefault);
  MessageTip.success('已进入平移视图');
  setMouseStyle(panView);
  userEvents.emit(KEYBOARD_VIEW, { isSelected: true });
  ctx2.viewer.sceneSetup.setToolBarControl(true);
  ToolbarMouseControlManager.state = TrackBallControlState.PAN;
  ctx2.viewer.sceneSetup.setMouseState(TrackBallControlState.PAN);
  document.addEventListener('mousedown', onMoveMouseDown, { capture: true });
  document.addEventListener('mouseup', onMoveMouseUp, { capture: true });
  document.addEventListener('wheel', onMouseWheel, { capture: true });
  return null;
}

function controlRotate() {
  if (ToolbarMouseControlManager.state === TrackBallControlState.ROTATE) {
    setControlDefault();
    return;
  }
  csEvent()
    .setState('control-rotate')
    .on(CENTEREVENTS.KEYUP, keyupEvent)
    .addExit(setControlDefault);
  MessageTip.success('已进入旋转视图');
  setMouseStyle(rotateView);
  userEvents.emit(KEYBOARD_VIEW, { isSelected: true });
  ctx2.viewer.sceneSetup.setToolBarControl(true);
  ctx2.viewer.sceneSetup.setMouseState(TrackBallControlState.ROTATE);
  ToolbarMouseControlManager.state = TrackBallControlState.ROTATE;
  document.addEventListener('mousedown', onRotateMouseDown, { capture: true });
  document.addEventListener('mouseup', onRotateMouseUp, { capture: true });
  document.addEventListener('wheel', onMouseWheel, { capture: true });
  return null;
}

function controlZoom() {
  if (ToolbarMouseControlManager.state === TrackBallControlState.ZOOM) {
    setControlDefault();
    return;
  }
  csEvent()
    .setState('control-zoom')
    .on(CENTEREVENTS.KEYUP, keyupEvent)
    .addExit(setControlDefault);
  MessageTip.success('已进入缩放视图');
  setMouseStyle(zoomView);
  userEvents.emit(KEYBOARD_VIEW, { isSelected: true });
  ctx2.viewer.sceneSetup.setToolBarControl(true);
  ctx2.viewer.sceneSetup.setMouseState(TrackBallControlState.ZOOM);
  ToolbarMouseControlManager.state = TrackBallControlState.ZOOM;
  document.addEventListener('mousedown', onZoomMouseDown, { capture: true });
  document.addEventListener('mouseup', onZoomMouseUp, { capture: true });
  document.addEventListener('wheel', onMouseWheel, { capture: true });
  return null;
}

export const ToolbarMouseControlManager = {
  state: TrackBallControlState.NONE,
};
